package com.ecarx.vhaltests.hy11.testcases.brightness;

import android.car.VehicleAreaSeat;
import android.car.VehicleAreaType;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;
import android.util.Log;

import androidx.test.platform.app.InstrumentationRegistry;

import com.ecarx.xui.adaptapi.car.IWrapper;
import com.ecarx.xui.adaptapi.car.property.IProperty;
import com.ecarx.xui.adaptapi.car.vehicle.IDayMode;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;


@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SmoothSettingBrightnessTest extends BrightnessTestBase {

    private static final String TAG = "SettingFuncBrightnessTest";

    private static int mPropertyId = -1;
    private static int mAutoPropertyId = -1;

    private static final int mAREA = VehicleAreaSeat.SEAT_ROW_1_CENTER;

    private static final int mGlobal_AREA = VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL;

    @BeforeClass
    public static void testInit() {
        IWrapper wrapper = com.ecarx.xui.adaptapi.car.Car.createWrapper(InstrumentationRegistry.getInstrumentation().getTargetContext());
        mPropertyId = wrapper.getWrappedPropertyId(IWrapper.WrappedIdType.ID_TYPE_FUNCTION, IDayMode.SETTING_FUNC_BRIGHTNESS_SCREEN).getPropertyId();
        mAutoPropertyId = wrapper.getWrappedPropertyId(IWrapper.WrappedIdType.ID_TYPE_FUNCTION, IProperty.SETTING_FUNC_BRIGHTNESS_AUTO_ADJUST).getPropertyId();
        delay();
    }

    @Test
    public void testBrightnessSmoothSetting_auto_highEnd_1() {
        setIsLowEndModel(false);

        mCarPropertyMgr.setBooleanProperty(mAutoPropertyId, mGlobal_AREA, false);
        delay();
        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, 0);
        delay(1000);
        Assert.assertEquals(mCarPropertyMgr.getIntProperty(mPropertyId, mAREA), 0);


        mockAmbIllmnFwdStsAmblillmn1And2(0, 195);//14
        mCarPropertyMgr.setBooleanProperty(mAutoPropertyId, mGlobal_AREA, true);
        delay(1500);
        int brightness = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Assert.assertTrue(brightness == 2);

        delay(2000);
        brightness = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Assert.assertTrue(brightness == 4);

        delay(2000);
        brightness = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Assert.assertTrue(brightness == 8);

        delay(2000);
        brightness = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Assert.assertTrue(brightness == 12 || brightness == 14);

        delay(2000);
        brightness = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Assert.assertEquals(brightness, 14);

        delay();
    }

    @Test
    public void testBrightnessSmoothSetting_auto_highEnd_2() {

        setIsLowEndModel(false);

        mCarPropertyMgr.setBooleanProperty(mAutoPropertyId, mGlobal_AREA, false);
        delay();
        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, 3);
        delay();
        Assert.assertEquals(mCarPropertyMgr.getIntProperty(mPropertyId, mAREA), 3);


        mockAmbIllmnFwdStsAmblillmn1And2(500, 0);//4
        mCarPropertyMgr.setBooleanProperty(mAutoPropertyId, mGlobal_AREA, true);
        delay(2000);
        int brightness = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Assert.assertEquals(brightness, 4);

        mockAmbIllmnFwdStsAmblillmn1And2(3000, 17);//12

        delay(2000);
        brightness = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Log.d(TAG, "brightnessNow:" + brightness);
        Assert.assertTrue("brightnessNow:" + brightness, brightness >= 4 && brightness < 14);


        delay(2000);
        brightness = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Log.d(TAG, "brightnessNow:" + brightness);
        Assert.assertTrue("brightnessNow:" + brightness, brightness > 4 && brightness < 14);


        delay(2000);
        brightness = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Log.d(TAG, "brightnessNow:" + brightness);
        Assert.assertTrue("brightnessNow:" + brightness, brightness > 4 && brightness < 14);

        mockAmbIllmnFwdStsAmblillmn1And2(500, 0);//4
        delay(6000);
        int brightness1 = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Log.d(TAG, "brightnessNow:" + brightness1);
        Assert.assertEquals(brightness1, 4);

        mCarPropertyMgr.setBooleanProperty(mAutoPropertyId, mGlobal_AREA, false);
    }


    @Test
    public void testSmoothSettingBrightness_auto_day_to_night_lowEnd() {

        setIsLowEndModel(true);

        mCarPropertyMgr.setBooleanProperty(mAutoPropertyId, mGlobal_AREA, true);
        delay();

        mockDayNightTwliBriSts(true);
        delay(6000);
        int dayBrightness = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Assert.assertEquals(dayBrightness, 12);

        mockDayNightTwliBriSts(false);
        delay(5000);
        int nightBrightness = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Assert.assertEquals(nightBrightness, 4);
        delay();
    }

    @Test
    public void testSmoothSettingBrightness_auto_night_to_day_lowEnd() {

        setIsLowEndModel(true);

        mCarPropertyMgr.setBooleanProperty(mAutoPropertyId, mGlobal_AREA, true);
        delay();

        mockDayNightTwliBriSts(false);
        delay(6000);
        int nightBrightness = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Assert.assertEquals(nightBrightness, 4);

        mockDayNightTwliBriSts(true);
        delay(4000);
        int dayBrightness = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Assert.assertEquals(dayBrightness, 12);

        delay();
    }


    @Test
    public void testBrightnessSmoothSetting_auto_lowEnd_callback() {

        mCarPropertyMgr.setBooleanProperty(mAutoPropertyId, mGlobal_AREA, false);
        delay();
        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, 0);
        delay();
        Assert.assertEquals(mCarPropertyMgr.getIntProperty(mPropertyId, mAREA), 0);

        setIsLowEndModel(true);
        delay();

        mCarPropertyMgr.setBooleanProperty(mAutoPropertyId, mGlobal_AREA, true);
        delay();

        int brightness = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Log.d(TAG, "currentValue:" + brightness);

        final int[] times = {0};
        int[] values = new int[]{0, 2, 4, 8, 12, 14};
        final long[] start = {System.currentTimeMillis()};

        CarPropertyManager.CarPropertyEventCallback carPropertyEventCallback = new CarPropertyManager.CarPropertyEventCallback() {
            @Override
            public void onChangeEvent(CarPropertyValue carPropertyValue) {

                int value = (Integer) carPropertyValue.getValue();

                Assert.assertTrue("currentValue:" + value, value == 0 || value == 2 || value == 4 || value == 8 || value == 12);

                Assert.assertTrue("currentValue:" + value, value == values[times[0]]);
                times[0]++;
                long end = System.currentTimeMillis();
                long cost = end - start[0];
                Assert.assertTrue(cost < 2500);
                Log.d(TAG, "currentValue:" + value + "  cost:" + cost);
                start[0] = end;
            }

            @Override
            public void onErrorEvent(int i, int i1) {

            }
        };
        mCarPropertyMgr.registerCallback(carPropertyEventCallback, mPropertyId, 0);

        mockDayNightTwliBriSts(false);
        delay(5000);
        start[0] = System.currentTimeMillis();
        mockDayNightTwliBriSts(true);
        delay(5000);

        mCarPropertyMgr.unregisterCallback(carPropertyEventCallback);
    }


    @Test
    public void testBrightnessSmoothSetting_auto_highEnd_callback() {

        mCarPropertyMgr.setBooleanProperty(mAutoPropertyId, mGlobal_AREA, false);
        delay();
        mCarPropertyMgr.setIntProperty(mPropertyId, mAREA, 0);
        delay();
        Assert.assertEquals(mCarPropertyMgr.getIntProperty(mPropertyId, mAREA), 0);

        setIsLowEndModel(false);
        delay();

        mCarPropertyMgr.setBooleanProperty(mAutoPropertyId, mGlobal_AREA, true);
        delay();

        int brightness = mCarPropertyMgr.getIntProperty(mPropertyId, mAREA);
        Log.d(TAG, "currentValue:" + brightness);

        final int[] times = {0};
        int[] values = new int[]{0, 2, 4, 8, 12, 14};
        final long[] start = {System.currentTimeMillis()};


        CarPropertyManager.CarPropertyEventCallback carPropertyEventCallback = new CarPropertyManager.CarPropertyEventCallback() {
            @Override
            public void onChangeEvent(CarPropertyValue carPropertyValue) {

                int value = (Integer) carPropertyValue.getValue();

                Assert.assertTrue("currentValue:" + value, value == values[times[0]]);
                times[0]++;
                long end = System.currentTimeMillis();
                long cost = end - start[0];
                Assert.assertTrue(cost < 2500);
                Log.d(TAG, "currentValue:" + value + "  cost:" + cost);
                start[0] = end;
            }

            @Override
            public void onErrorEvent(int i, int i1) {

            }
        };
        mCarPropertyMgr.registerCallback(carPropertyEventCallback, mPropertyId, 0);

        mockAmbIllmnFwdStsAmblillmn1And2(300, 0);//4
        delay(5000);
        start[0] = System.currentTimeMillis();
        mockAmbIllmnFwdStsAmblillmn1And2(0, 195);//14
        delay(7000);

        mCarPropertyMgr.unregisterCallback(carPropertyEventCallback);

    }


}
